package daobeauty.interceptor.returntype.executor.criteria;

import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;

import daobeauty.dao.Limiting;
import daobeauty.dao.Sorting;
import daobeauty.interceptor.returntype.executor.ExecutionStrategy;
import daobeauty.interceptor.returntype.handler.ReturnTypeHandler;
import daobeauty.interceptor.returntype.handler.ReturnTypeHandlerManager;

/**
 * Executes queries corresponding to the given limiting and uses a returntypehandler
 * to generate appropriate return type.
 * 
 * @author M. Serhat Cinar
 *
 */
public class CriteriaExecutor implements ExecutionStrategy{
	private static final Log LOG = LogFactory.getLog(CriteriaExecutor.class);
	
	private ReturnTypeHandler returnTypeHandler;
	private CriteriaExecutionStrategy criteriaExecutionStartegy;
	
	public CriteriaExecutor(Class returnType){
		returnTypeHandler = ReturnTypeHandlerManager.getByOutType(returnType);
		if (Collection.class.isAssignableFrom(returnType) || Object[].class.isAssignableFrom(returnType)){
			criteriaExecutionStartegy = ListCriteriaExecutionStrategy.INSTANCE; 
		}
		else{
			criteriaExecutionStartegy = UniqueResultCriteriaExecutionStrategy.INSTANCE;
		}
		if (LOG.isDebugEnabled()){
			LOG.debug("CriteriaExecutor: "+criteriaExecutionStartegy);
		}
	}
	
	public Object execute(Criteria criteria, Limiting limiting, Sorting sorting){
		return criteriaExecutionStartegy.execute(returnTypeHandler, criteria, limiting, sorting);
	}

	public Object execute(Object criteriaOrQuery, Limiting limiting, Sorting sorting) {
		return execute((Criteria) criteriaOrQuery, limiting, sorting);
	}
}
